﻿using System.Reflection;
using Volo.Abp.DependencyInjection;
using AbpCodeGenerater.Core;
using System.IO;

namespace AbpCodeGenerater
{
    public partial class MainWindow : Form, ISingletonDependency
    {
        protected string RootFilePath { get; set; } = string.Empty;
        protected string FileName { get; set; } = string.Empty;
        protected string FilePrefix { get; set; } = string.Empty;
        protected string BaseFilePath => RootFilePath.Replace(FileName, "");
        protected string ProjectName => FilePrefix.Substring(FilePrefix.LastIndexOf(".") + 1, FilePrefix.Length - FilePrefix.LastIndexOf(".") - 1);
        protected string[] Folders { get; set; }
        protected TreeNode RootNode { get; set; }

        public IAbpLazyServiceProvider LazyServiceProvider { get; set; }

        protected ISolutionLoader SolutionLoader => LazyServiceProvider.LazyGetRequiredService<ISolutionLoader>();

        protected AbpSolution AbpSolution { get; set; }

        protected AbpDomainClass AbpDomainClass { get; set; }

        public MainWindow()
        {
            InitializeComponent();
        }

        private void loadMenu_Click(object sender, EventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Filter = "C# solution files (*.sln)|*.sln";
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var solutionFilePath = dialog.FileName;
                AbpSolution = SolutionLoader.LoadFrom(solutionFilePath);

                fileTree.Nodes.Clear();
                fileTree.Nodes.Add(AbpSolution.ToTreeNode());
            }
        }

        private void fileTree_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            var startUpProjectPath = AbpSolution?.StartUpProject?.Path;
            if (string.IsNullOrWhiteSpace(startUpProjectPath))
            {
                MessageBox.Show("未找到启动项目路径！");
                return;
            }

            var abpClass = e.Node.Tag as AbpClass;
            if (abpClass == null || abpClass.AbpProject == null || string.IsNullOrWhiteSpace(abpClass.FullPath) || abpClass.Name == null) return;

            var dllPath = Path.Combine(AbpSolution?.DirectioryPath ?? string.Empty, startUpProjectPath, "bin", "Debug", "net6.0", $"{abpClass.AbpProject.Name}.dll");
            var assembly = Assembly.LoadFrom(dllPath);

            var type = assembly.GetTypes().FirstOrDefault(x => x.Name == abpClass.Name);
            if (type == null)
            {
                MessageBox.Show($"未找到类型{abpClass.Name}");
                return;
            }
            if (!type.GetInterfaces().Any(x => x.Name == "IEntity"))
            {
                MessageBox.Show($"类型{abpClass.Name}不是Domain类型");
                return;
            }

            if (AbpSolution == null) return;

            abpClass.LoadClass();
            AbpDomainClass = new AbpDomainClass(abpClass, type);
            txtContent.Text = abpClass.Context;
        }

        private void simpleTreeGenerateMenu_Click(object sender, EventArgs e)
        {
            if (AbpDomainClass == null)
            {
                MessageBox.Show("请先选择领域模型");
                return;
            }

            if (!AbpDomainClass.ClassType.GetInterfaces().Any(x => x.Name == "ITree`1"))
            {
                MessageBox.Show("所选领域模型不是树形结构");
                return;
            }

            var treeDomainGenerateWindow = new TreeDomainGenerateWindow(AbpDomainClass);
            treeDomainGenerateWindow.ShowDialog();
        }

        private void simpleTreeUIGenerateMenu_Click(object sender, EventArgs e)
        {
            if (AbpDomainClass == null)
            {
                MessageBox.Show("请先选择领域模型");
                return;
            }

            if (!AbpDomainClass.ClassType.GetInterfaces().Any(x => x.Name == "ITree`1"))
            {
                MessageBox.Show("所选领域模型不是树形结构");
                return;
            }

            var treeDomainUIGenerateWindow = new TreeDomainUIGenerateWindow(AbpDomainClass);
            treeDomainUIGenerateWindow.ShowDialog();
        }

        private void simpleArchiveGenerateMenu_Click(object sender, EventArgs e)
        {
            if (AbpDomainClass == null)
            {
                MessageBox.Show("请先选择领域模型");
                return;
            }

            if (!AbpDomainClass.ClassType.GetInterfaces().Any(x => x.Name == "IArchiveAggregateRoot"))
            {
                MessageBox.Show("所选领域模型不是档案类型");
                return;
            }

            var simplyArchiveGenerateWindow = new SimpleArchiveGenerateWindow(AbpDomainClass);
            simplyArchiveGenerateWindow.ShowDialog();
        }

        private void simpleArchiveUIGenerateMenu_Click(object sender, EventArgs e)
        {
            if (AbpDomainClass == null)
            {
                MessageBox.Show("请先选择领域模型");
                return;
            }

            if (!AbpDomainClass.ClassType.GetInterfaces().Any(x => x.Name == "IArchiveAggregateRoot"))
            {
                MessageBox.Show("所选领域模型不是档案类型");
                return;
            }

            var simplyArchiveUIGenerateWindow = new SimpleArchiveUIGenerateWindow(AbpDomainClass);
            simplyArchiveUIGenerateWindow.ShowDialog();
        }

        private void multiArchiveGenerateMenu_Click(object sender, EventArgs e)
        {
            if (AbpDomainClass == null)
            {
                MessageBox.Show("请先选择领域模型");
                return;
            }

            var interfaceType = AbpDomainClass.ClassType.GetInterfaces().FirstOrDefault(x => x.Name.StartsWith("IMultiArchiveAggregateRoot`"));
            if (interfaceType == null)
            {
                MessageBox.Show("所选领域模型不是复杂档案类型");
                return;
            }

            var childType = interfaceType.GenericTypeArguments[0];
            var childClass = new AbpClass();
            childClass.Name = childType.Name;
            childClass.FileName = $"{childType.Name}.cs";
            childClass.FullPath = Path.Combine(AbpDomainClass.FullDirectoryPath ?? "", childClass.FileName);
            childClass.AbpProject = AbpDomainClass.AbpProject;
            childClass.LoadClass();

            var childDomainClass = new AbpDomainClass(childClass, childType);
            var multiArchiveGenerateWindow = new MultiArchiveGenerateWindow(AbpDomainClass, childDomainClass);
            multiArchiveGenerateWindow.ShowDialog();
        }

        private void multiArchiveUIGenerateMenu_Click(object sender, EventArgs e)
        {

        }
    }
}
